/*
 * View class, volgens MVC. toont alles wat getoond dient te worden aan de gebruiker, en geeft acties van de gebruiker door aan de controller danwel model.
 */

package meesterbrein;

import java.awt.Color;
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.SpringLayout;


/**
 *
 * @author Laurens van Dijk, s3012557 en Gerdriaan Mulder, s3048764
 */
public class View implements ActionListener
{
    public static final int WWIDTH = 480, WHEIGHT = 640; //NB: Ik weet niet zeker of dit onder view of controller hoort. - L
    public final static int NUMPIECES = 4, NUMROWS = 5;

    public static boolean checkBtnPressed = false;

    public JButton quitbtn, newgamebtn, testbtn, addbtn, funcbtn;
    public JButton[] guessbtn, solution, pinsetbtn;
    public JButton[][] testedcombinations, pinbtn; //moehaha 2D-arrays, WHAT NOW BITCHES? - L
    private JLabel headerLabel;
    private SpringLayout layout;
    public Container f;
    public JFrame frame; //tumdiedum, alles public :+ lekker makkelijk aanprutsen met de controller. - L
    private Model m;


    /**
     * Functie om de oplossing te tonen.
     */
    public void clearBoard()
    {
        addbtn.setEnabled(true);
        for(int i = 0; i < NUMPIECES; i++)
        {
            solution[i].setBackground(Color.GRAY);
            guessbtn[i].setBackground(Color.GRAY);
        }

        for(int x=0; x<NUMROWS; x++)
        {
            for(int y=0; y<NUMPIECES; y++)
            {
                pinbtn[x][y].setBackground(Color.GRAY);
                testedcombinations[x][y].setBackground(Color.GRAY);
            }
        }


    }

    /**
     * toon de oplossing.
     * @param ai - de huidige ai.
     */
    public void showSolution(Maker ai)
    {
        for(int i = 0; i < NUMPIECES; i++) {
            solution[i].setBackground(ai.getSolutionByIndex(i).getColor());
        }
        addbtn.setEnabled(false);
    }

    /**
     * Functie om de constraints aan alle buttons toe te voegen, zodat ze ook daadwerkelijk gerendered worden waar ze horen.
     */
    public void addConstraints()
    {
                //en constraints toevoegen.
        layout.putConstraint(SpringLayout.EAST, quitbtn, -5, SpringLayout.EAST, f);
        layout.putConstraint(SpringLayout.NORTH, quitbtn, 10, SpringLayout.NORTH, f);
        layout.putConstraint(SpringLayout.WEST, quitbtn, -125, SpringLayout.EAST, f);

        layout.putConstraint(SpringLayout.EAST, newgamebtn, -5, SpringLayout.EAST, f);
        layout.putConstraint(SpringLayout.NORTH, newgamebtn, 10, SpringLayout.SOUTH, quitbtn);
        layout.putConstraint(SpringLayout.WEST, newgamebtn, -125, SpringLayout.EAST, f);

        layout.putConstraint(SpringLayout.EAST, funcbtn, -5, SpringLayout.EAST, f);
        if (Controller.mensBreker) {
            layout.putConstraint(SpringLayout.NORTH, funcbtn, 10, SpringLayout.SOUTH, newgamebtn);
        } else {
            layout.putConstraint(SpringLayout.SOUTH, funcbtn, -15, SpringLayout.NORTH, addbtn);
        }
        layout.putConstraint(SpringLayout.WEST, funcbtn, -180, SpringLayout.EAST, f);

        layout.putConstraint(SpringLayout.EAST, addbtn, -80, SpringLayout.EAST, f);
        layout.putConstraint(SpringLayout.SOUTH, addbtn, -30, SpringLayout.SOUTH, f);

        for(int i=0; i<NUMPIECES; i++)
        {
            layout.putConstraint(SpringLayout.WEST, guessbtn[i], 50*i+70, SpringLayout.WEST, f); //meh, vieze position-berekening. - L
            layout.putConstraint(SpringLayout.SOUTH, guessbtn[i], -30, SpringLayout.SOUTH, f);

            layout.putConstraint(SpringLayout.WEST, solution[i], 50*i+70, SpringLayout.WEST, f); //meh, vieze position-berekening. - L
            layout.putConstraint(SpringLayout.NORTH, solution[i], 55, SpringLayout.NORTH, f);

            if (!Controller.mensBreker) {
                if (i == 0) {
                    layout.putConstraint(SpringLayout.WEST, pinsetbtn[i], 50*i+300, SpringLayout.WEST, f);
                } else {
                    layout.putConstraint(SpringLayout.WEST, pinsetbtn[i], 10, SpringLayout.EAST, pinsetbtn[i-1]);
                }
                layout.putConstraint(SpringLayout.SOUTH, pinsetbtn[i], -100, SpringLayout.SOUTH, f);
            }
        }

        for(int y=0; y<NUMROWS; y++)
        {
            for(int x=0; x<NUMPIECES; x++)
            {
                 layout.putConstraint(SpringLayout.WEST, testedcombinations[y][x], 50*x+70, SpringLayout.WEST, f); //meh, vieze position-berekening. - L
                 layout.putConstraint(SpringLayout.SOUTH, testedcombinations[y][x], -75*y-150, SpringLayout.SOUTH, f);
                 if (x == 0) {
                    layout.putConstraint(SpringLayout.WEST, pinbtn[y][x], 50*x+300, SpringLayout.WEST, f);
                 } else {
                     layout.putConstraint(SpringLayout.WEST, pinbtn[y][x], 10, SpringLayout.EAST, pinbtn[y][x-1]);
                 }
                 layout.putConstraint(SpringLayout.SOUTH, pinbtn[y][x], -75*y-150, SpringLayout.SOUTH, f);
            }
        }
    }

    /**
     * Functie om actionlisteners aan de buttons die dit nodig hebben toe te voegen.
     */
    public void addActionListeners()
    {
        quitbtn.addActionListener(this);
        newgamebtn.addActionListener(this);
        addbtn.addActionListener(this);
        funcbtn.addActionListener(this);

        for(int i=0; i<NUMPIECES; i++)
        {
            guessbtn[i].addActionListener(this); //tumdiedum, lekker makkelijk uitlezen, zo. - L
            if(!Controller.mensBreker) {
                pinsetbtn[i].addActionListener(this);
            }
        }

    }

    /**
     * functie die alle buttons daadwerkelijk aanmaakt en toevoegt aan de container f.
     */
    public void makeArray()
    {
        for(int i=0; i<NUMPIECES; i++) {
            guessbtn[i] = new JButton("O");
            solution[i] = new JButton("?");
            pinsetbtn[i] = new JButton("");
            f.add(guessbtn[i]);
            f.add(solution[i]);
            if (!Controller.mensBreker) {
                f.add(pinsetbtn[i]);
                pinsetbtn[i].setBackground(Color.BLACK);
                pinsetbtn[i].setPreferredSize(new Dimension(20, 20));
            }
            guessbtn[i].setBackground(Color.GRAY);
            solution[i].setBackground(Color.GRAY);

        }

        for(int y=0; y<NUMROWS; y++)
        {
            for(int x=0; x<NUMPIECES; x++)
            {
                testedcombinations[y][x] = new JButton("O");
                f.add(testedcombinations[y][x]);
                testedcombinations[y][x].setBackground(Color.GRAY);

                pinbtn[y][x] = new JButton("");
                f.add(pinbtn[y][x]);
                pinbtn[y][x].setPreferredSize(new Dimension(20, 20));
                pinbtn[y][x].setBackground(Color.GRAY);
            }
        }
    }

    /**
     * functie om alle JButtons daadwerkelijk te creeren.
     */
    public void addButtons()
    {
         //en dan knopjes spammen. actionlisteners moeten er later ingehackt worden. - L
        quitbtn = new JButton("Quit");
        newgamebtn = new JButton("New Game");
        funcbtn = (Controller.mensBreker) ? new JButton("Show Solution") : new JButton("Set Pins");
        guessbtn = new JButton[NUMPIECES]; //de array voor de keuze van de gebruiker. - L
        solution = new JButton[NUMPIECES];
        pinsetbtn = new JButton[NUMPIECES];
        testedcombinations = new JButton[NUMROWS][NUMPIECES];
        addbtn = (Controller.mensBreker) ? new JButton("Check") : new JButton("Set Code");
        pinbtn = new JButton[NUMROWS][NUMPIECES];

        makeArray(); //even opgesplitst, functie werd te groot.

        f.add(quitbtn);
        f.add(newgamebtn);
        f.add(addbtn);
        f.add(funcbtn);
        f.setVisible(true);

    }

    /**
     * kleine, simpele functie die ervoor zorgt dat het frame de juiste dimensies heeft, zichtbaar is, en correct afsluit.
     */
    public void packProgram()
    {
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    }

    /**
     * functie die de interface daarwerkelijk tekent.
     * @param width - breedte van het venster
     * @param height - hoogte van het venster
     */
    public void interfaceGen(int width, int height)
    {
        frame = new JFrame("MMPM"); //maken van een frame met juiste dimensies
        frame.setSize(width, height);
        frame.setResizable(false); //DOHOHO

        f = frame.getContentPane(); //en een container met springlayout
        layout = new SpringLayout();
        f.setPreferredSize(new Dimension(width, height)); //how do i shot minimumformaat? #DIKKECARE - L
        f.setLayout(layout);
        f.add(new JLabel("Mastermind!"));

        /* TODO: headerlabel iets fixen - G
        headerLabel = new JLabel("Informatie");
        headerLabel.setLocation(5, 30);
        f.add(headerLabel);*/

        addButtons();
        addConstraints();
        addActionListeners(); //drie functies, wat netter dan een _huge_ functie. - L
        packProgram(); //mja ach. niet supermooi, maar maakt het aesthetisch net wat aangenamer. - L

    }
    /**
     * Constructor. doet niet bijster veel, maar roept interfaceGen aan.
     * @param _m model dat de view moet gebruiken
     */
    public View(Model _m)
    {
        m = _m;
      interfaceGen(WWIDTH, WHEIGHT);

    }

    /**
     * De meest dubieuze functie in ons programma, woei!
     *
     * Punt is dat dit een vrij lastige functie is om te implementeren, en dit volgens MVC in View hoort (actions doorgeven aan de controller),
     * maar dat dit in onze ogen strict genomen toch een controller-functie is..
     * @param ae
     */
    @Override
	public void actionPerformed(ActionEvent ae) {
		if (ae.getSource() == quitbtn) {
			System.exit(0);
		}
                else if(ae.getSource() == newgamebtn) {
                       // Controller.startGame(); //doorgeven aan controller, volgens MVC.
                    Controller.genereerSpelBord();
                }
                else if(ae.getSource() == funcbtn) {
                        //Controller.showSolution(); //doorgeven aan controller, volgens MVC.
                    Controller.processFuncbtn(); // multi-purpose knopje
                }
                else if (ae.getSource() == guessbtn[0]) {
                    Controller.guessNextColour(guessbtn[0]);
                }
                else if (ae.getSource() == guessbtn[1]) {
                    Controller.guessNextColour(guessbtn[1]);
                }
                else if (ae.getSource() == guessbtn[2]) {
                    Controller.guessNextColour(guessbtn[2]);
                }
                else if (ae.getSource() == guessbtn[3]) {
                    Controller.guessNextColour(guessbtn[3]);
                }
                else if (ae.getSource() == pinsetbtn[0]) {
                    Controller.guessNextPin(pinsetbtn[0]);
                }
                else if (ae.getSource() == pinsetbtn[1]) {
                    Controller.guessNextPin(pinsetbtn[1]);
                }
                else if (ae.getSource() == pinsetbtn[2]) {
                    Controller.guessNextPin(pinsetbtn[2]);
                }
                else if (ae.getSource() == pinsetbtn[3]) {
                    Controller.guessNextPin(pinsetbtn[3]);
                }
                else if (ae.getSource() == addbtn) {
                    if (!Controller.mensBreker) {
                        if (!Controller.spelGestart) {
                            Model.Kleur codekleuren[] = m.getKleurFromJButtons(guessbtn);
                            m.combinatieNaarSolution(codekleuren, solution);
                            if (m.getSolutionState()) {
                                addbtn.setEnabled(false);
                                Controller.spelGestart = true;
                            }
                        }
                    } else {
                        System.out.println("DEBUG: View, CheckBtn pressed OMGWTF");
                        if (Controller.breakerBeurt) {
                            Model.Kleur guesskleuren[] = m.getKleurFromJButtons(guessbtn);
                            if (m.combinatieNaarOverzicht(guesskleuren, testedcombinations)) {
                                checkBtnPressed = true;
                                Controller.volgendeSpeler();
                            }
                        }
                    }
                }

    }

    /**
     * toon de kleuren van de gekozen pinnen.
     */
    public void zetPinnen() {
        Model.Pin kleuren[] = m.getPinsFromJButtons(pinsetbtn);
        m.hintsNaarPinnetjes(kleuren, pinbtn);
    }

    /**
     * idem als zetPinnen()
     * @param p - een array van pinnen.
     */
    public void zetPinnen(Model.Pin[] p) {
        m.hintsNaarPinnetjes(p, pinbtn);
    }

    /**
     * geef de laatste combinatie terug.
     * @return
     */
    public Model.Kleur[] getLastCombination() {
        if (Controller.aantalCombinaties > 0) {
            return m.getKleurFromJButtons(testedcombinations[Controller.aantalCombinaties-1]);
        }
        return new Model.Kleur[0];
    }

    /**
     *
     */
    public void setLastCombination() {

    }
}